home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 4 / Amiga Tools 4.iso / tools / netzwerk / tcp-ip / ipdial_v1.9 / debug / IPDial.c < prev    next >
C/C++ Source or Header  |  1995-11-18  |  25KB  |  1,140 lines

  1. /**
  2. ***  IPDial     Script program for initializing a SLIP connection
  3. ***  Copyright  (C)   1994    Jochen Wiedmann
  4. ***
  5. ***  This program is free software; you can redistribute it and/or modify
  6. ***  it under the terms of the GNU General Public License as published by
  7. ***  the Free Software Foundation; either version 2 of the License, or
  8. ***  (at your option) any later version.
  9. ***
  10. ***  This program is distributed in the hope that it will be useful,
  11. ***  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. ***  GNU General Public License for more details.
  14. ***
  15. ***  You should have received a copy of the GNU General Public License
  16. ***  along with this program; if not, write to the Free Software
  17. ***  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. ***
  19. ***
  20. ***  This is the main part of the program.
  21. ***
  22. ***
  23. ***  Computer: Amiga 1200                       Compiler: Dice 3.01
  24. ***
  25. ***  Author:    Jochen Wiedmann
  26. ***             Am Eisteich 9
  27. ***             72555 Metzingen
  28. ***             Germany
  29. ***
  30. ***             Phone: (+0049) 7123 / 14881
  31. ***             Internet: wiedmann@neckar-alb.de
  32. ***
  33. ***
  34. ***  History:   V 1.1   23.11.94        Initial version
  35. ***
  36. ***             V 1.2   27.02.95        Added terminal mode
  37. ***                                     Now using ReadArgs() for
  38. ***                                     command line parsing.
  39. ***
  40. ***             V 1.3   09.03.95        Added environment variable
  41. ***                                     aupport to "send" command.
  42. ***                                     Added unit support.
  43. ***
  44. ***             V 1.4   21.04.95        Added "system" command.
  45. ***                                     Added environment variable
  46. ***                                     support to "echo" command.
  47. ***                                     Terminal mode now converts
  48. ***                                     LF to CR/LF, so that modem
  49. ***                                     recognizes commands.
  50. ***                                     (Let's hope, that will still
  51. ***                                     work for entering passwords. :-(
  52. ***
  53. ***             V 1.5   30.04.95        Added "scan" command.
  54. ***
  55. ***             V 1.6   26.06.95        "delay" command supporting
  56. ***                                     ticks; ParseString()
  57. ***                                     supporting octal characters;
  58. ***                                     "wait" command using
  59. ***                                     ParseString()
  60. ***                                     (All Suggested by Will Bow.)
  61. ***
  62. ***                                     Fixed bug in SerialSend():
  63. ***                                     *.io_Device = *.io_Unit
  64. ***
  65. ***             V 1.7   22.07.95        Added ECHO, RAW and EOF options
  66. ***                                     to "terminal" command.
  67. ***                                     (Suggested by Klaus Heinz.)
  68. ***
  69. ***                                     Added BAUD option to command
  70. ***                                     line.
  71. ***
  72. ***                                     Added "setvar" command.
  73. ***
  74. ***             v 1.8   24.11.95        Put a 10 tick delay after the
  75. ***                                     DoIO() call in DeviceIODo()
  76. **/
  77. #define VERSION     1
  78. #define REVISION    8
  79. #define VSTRING     "IPDial 1.8 (24.11.95)"
  80. #define VERSTAG     "\0$VER: IPDial 1.8 (24.11.95)"
  81. /**
  82. ***  Include files
  83. **/
  84. #include "IPDial.h"
  85. #include <ctype.h>
  86. #include <clib/alib_protos.h>
  87. /**
  88. ***  This structure describes one command. All commands are stored
  89. ***  in a table at the end of the file.
  90. **/
  91. struct ScriptLine;
  92. typedef VOID (*CommandFunc) (struct ScriptLine *);
  93. struct Command
  94.   CommandFunc Func;
  95.   STRPTR Name;
  96. };
  97. /**
  98. ***  Each line of the script file is stored in a structure like below.
  99. **/
  100. struct ScriptLine
  101.   struct MinNode mn;
  102.   ULONG Num;
  103.   CommandFunc CommFunc;
  104.   STRPTR Label;
  105.   STRPTR Args;
  106. };
  107. /**
  108. ***  Global variables
  109. **/
  110. LONG StatusVar;
  111.  
  112. struct MinList ScriptLineList;
  113.  
  114. struct ScriptLine *CurrentScriptLine;
  115.  
  116. const UBYTE VersTag [] = VERSTAG;
  117. const UBYTE VString [] = VSTRING;
  118.  
  119. ULONG EchoMode = FALSE;
  120. ULONG VerboseMode = FALSE;
  121.  
  122. STRPTR SerialDeviceName = NULL;
  123.  
  124. struct RDArgs *MainRDArgs = NULL;
  125. /**
  126. ***  This function is used to skip blanks.
  127. **/
  128. STRPTR SkipBlanks(const UBYTE *ptr)
  129.   while(*ptr == ' '  ||  *ptr == '\t')
  130.   { 
  131.     ++ptr;
  132.   }
  133.   return((STRPTR) ptr);
  134. }
  135. /**
  136. ***  This function is used to parse a string for characters
  137. ***  like '\r' or '\n'. $VAR or ${VAR} may be used to insert
  138. ***  the value of environment variable VAR, $$ may be used to
  139. ***  insert the '$' character itself, likewise \\.
  140. ***
  141. ***  Returns a pointer to a string allocated with malloc().
  142. ***  It is the task of the caller, to free() this string.
  143. **/
  144. STRPTR ParseString(const UBYTE *ptr)
  145.   STRPTR result;
  146.   STATIC APTR parseBuffer = NULL;
  147.   /**
  148.   ***  Be sure, that buffer is valid.
  149.   **/
  150.   if (!parseBuffer  &&  !(parseBuffer = BufferCreate()))
  151.   { 
  152.     perror("malloc");
  153.     exit(10);
  154.   }
  155.   /**
  156.   ***  Clear the buffer.
  157.   **/
  158.   BufferClear(parseBuffer);
  159.  
  160.   while(*ptr)
  161.   { 
  162.     if (*ptr == '\\')
  163.     { 
  164.       ++ptr;
  165.       switch(*ptr)
  166.       { 
  167.         case 'r':
  168.             BufferExtend(parseBuffer, (STRPTR) "\r", 1);
  169.             break;
  170.           case 'n':
  171.             BufferExtend(parseBuffer, (STRPTR) "\n", 1);
  172.             break;
  173.           case '0':
  174.           case '1':
  175.           case '2':
  176.           case '3':
  177.           case '4':
  178.           case '5':
  179.           case '6':
  180.           case '7':
  181.             { 
  182.             char c;
  183.  
  184.               c = *ptr - '0';
  185.               if (ptr[1] >= '0'  &&  ptr[1] <= '7')
  186.               { 
  187.               c = (c << 3) + *(++ptr) - '0';
  188.                 if (ptr[1] >= '0'  &&  ptr[2] <= '7')
  189.                 { 
  190.                 c = (c << 3) + *(++ptr) - '0';
  191.                 }
  192.               }
  193.               BufferExtend(parseBuffer, (STRPTR) &c, 1);
  194.             }
  195.             break;
  196.           default:
  197.             BufferExtend(parseBuffer, ptr, 1);
  198.             break;
  199.       }
  200.       ++ptr;
  201.     }
  202.     else if (*ptr == '$')
  203.     { 
  204.       ++ptr;
  205.       if (*ptr == '$')
  206.       { 
  207.         BufferExtend(parseBuffer, (STRPTR) "$", 1);
  208.           ++ptr;
  209.       }
  210.       else
  211.       { 
  212.         char *varName;
  213.           const char* varPtr;
  214.           size_t varLen = 0;
  215.  
  216.           if (*ptr == '{')
  217.           { 
  218.           ++ptr;
  219.             varPtr = (const char*) ptr;
  220.             while (*ptr && *ptr != '}')
  221.             { 
  222.             ++ptr;
  223.               ++varLen;
  224.             }
  225.             if (*ptr == '}')
  226.             { 
  227.             ++ptr;
  228.             }
  229.           }
  230.           else
  231.           { 
  232.           varPtr = (const char*) ptr;
  233.             while (*ptr  &&  isalnum(*ptr))
  234.             { 
  235.             ++ptr;
  236.               ++varLen;
  237.             }
  238.           }
  239.  
  240.           if (!(varName = malloc(varLen + 1)))
  241.           { 
  242.           perror("malloc");
  243.             exit(10);
  244.           }
  245.           strncpy(varName, varPtr, varLen);
  246.           varName[varLen] = '\0';
  247.  
  248.           if ((varPtr = getenv(varName)))
  249.           { 
  250.           BufferExtend(parseBuffer, (STRPTR) varPtr, strlen(varPtr));
  251.           }
  252.       }
  253.     }
  254.     else
  255.     { 
  256.       BufferExtend(parseBuffer, ptr, 1);
  257.       ++ptr;
  258.     }
  259.   }
  260.  
  261.   BufferExtend(parseBuffer, (STRPTR) "", 1);
  262.  
  263.   if (!(result = (STRPTR) strdup((char*) BufferBuffer(parseBuffer))))
  264.   { 
  265.     perror("malloc");
  266.     exit(10);
  267.   }
  268.  
  269.   return(result);
  270. }
  271. /**
  272. ***  This is an empty function. Just to allow lines with labels only.
  273. **/
  274. VOID NoneFunc(struct ScriptLine *line)
  275. {
  276. }
  277. /**
  278. ***  This is the echo function.
  279. **/
  280. VOID EchoFunc(struct ScriptLine *line)
  281.   STRPTR *args;
  282.   int i;
  283.  
  284.   if (!StrReadArgs(line->Args, (LONG *) &args, (STRPTR) "ARGS/M"))
  285.   { 
  286.     fprintf(stderr, "Line %ld: Argument or memory error\n", line->Num);
  287.     exit(10);
  288.   }
  289.  
  290.   for(i = 0;  *args;  ++i, ++args)
  291.   { 
  292.     char *str;
  293.  
  294.     if (i)
  295.     { 
  296.       putchar(' ');
  297.     }
  298.     str = (char*) ParseString(*args);
  299.     fputs((char *) str, stdout);
  300.     fflush(stdout);
  301.     free(str);
  302.   }
  303. }
  304. /**
  305. ***  This is the device function.
  306. **/
  307. VOID DeviceFunc(struct ScriptLine *line)
  308.   struct
  309.   { 
  310.     STRPTR Device;
  311.     STRPTR Protocol;
  312.     LONG *Unit;
  313.   } args;
  314.  
  315.   if (SerialDeviceName)
  316.   { 
  317.     fprintf(stderr, "Line %ld: Device already open, ignoring.\n", line->Num);
  318.   }
  319.  
  320.   args.Unit = NULL;
  321.   args.Device = NULL;
  322.   args.Protocol = NULL;
  323.  
  324.   if (!StrReadArgs(line->Args, (LONG *) &args,
  325.           (STRPTR) "DEVICE,PROTOCOL,UNIT/K/N"))
  326.   { 
  327.     fprintf(stderr, "Line %ld: Argument or memory error\n", line->Num);
  328.     exit(10);
  329.   }
  330.  
  331.   if (!args.Device)
  332.   { 
  333.     fprintf(stderr, "Line %ld: Missing device name.\n", line->Num);
  334.     exit(10);
  335.   }
  336.   if (!(SerialDeviceName = (STRPTR) strdup((char *) args.Device)))
  337.   { 
  338.     perror("malloc");
  339.     exit(10);
  340.   }
  341.  
  342.   if (VerboseMode)
  343.   { 
  344.     printf("DeviceFunc: Opening %s.\n", args.Device);
  345.   }
  346.  
  347.   if (!SerialOpen(args.Device, args.Protocol, args.Unit ? *args.Unit : 0))
  348.   { 
  349.     fprintf(stderr, "Line %ld: Unknown protocol.\n", line->Num);
  350.     exit(10);
  351.   }
  352. }
  353. /**
  354. ***  This function is used to set the serial.device parameters.
  355. **/
  356. VOID SetFunc(struct ScriptLine *line)
  357.   struct
  358.   { 
  359.     ULONG *Baud;
  360.     ULONG *DataBits;
  361.     ULONG *StopBits;
  362.     ULONG *BufSize;
  363.     STRPTR Parity;
  364.     STRPTR Protocol;
  365.   } args;
  366.  
  367.   if (!SerialDeviceName)
  368.   { 
  369.     fprintf(stderr, "Line %ld: Must open serial.device first.\n", line->Num);
  370.     exit(10);
  371.   }
  372.  
  373.   args.Baud = NULL;
  374.   args.DataBits = NULL;
  375.   args.StopBits = NULL;
  376.   args.BufSize = NULL;
  377.   args.Parity = NULL;
  378.   args.Protocol = NULL;
  379.  
  380.   if (!(StrReadArgs(line->Args, (LONG *) &args,
  381.           (STRPTR) "BAUD/K/N,DATABITS/K/N,STOPBITS/K/N,BUFSIZE/K/N,"
  382.           "PARITY/K,PROTOCOL/K")))
  383.   { 
  384.     fprintf(stderr, "Line %ld: Argument or memory error.\n", line->Num);
  385.     exit(10);
  386.   }
  387.  
  388.   if (args.Baud)
  389.   { 
  390.     SerialSetBaud(*args.Baud);
  391.   }
  392.   if (args.DataBits)
  393.   { 
  394.     SerialSetDataBits(*args.DataBits);
  395.   }
  396.   if (args.StopBits)
  397.   { 
  398.     SerialSetStopBits(*args.StopBits);
  399.   }
  400.   if (args.BufSize)
  401.   { 
  402.     SerialSetBufSize(*args.BufSize);
  403.   }
  404.   if (args.Parity)
  405.   {
  406.     if (!SerialSetParity(args.Parity))
  407.     { 
  408.       fprintf(stderr, "Line %ld: Unknown parity.\n", line->Num);
  409.       exit(10);
  410.     }
  411.   }
  412.   if (args.Protocol)
  413.   {
  414.     if (!SerialSetProtocol(args.Protocol))
  415.     { 
  416.       fprintf(stderr, "Line %ld: Unknown protocol.\n", line->Num);
  417.       exit(10);
  418.     }
  419.   }
  420.  
  421.   if (VerboseMode)
  422.   { 
  423.     printf("SetFunc: %s Parameters modified:\n\n", SerialDeviceName);
  424.     SerialShowParms();
  425.   }
  426. }
  427. /**
  428. ***  This function shows the serial.device parameters.
  429. **/
  430. VOID ShowParmsFunc(struct ScriptLine *line)
  431.   if (!SerialDeviceName)
  432.   { 
  433.     fprintf(stderr, "Line %ld: Must open serial.device first.\n", line->Num);
  434.     exit(10);
  435.   }
  436.  
  437.   printf("%s Parameters:\n\n", SerialDeviceName);
  438.   SerialShowParms();
  439. }
  440. /**
  441. ***  This function sends a string to the serial.device.
  442. **/
  443. VOID SendFunc(struct ScriptLine *line)
  444.   STRPTR *args;
  445.  
  446.   if (VerboseMode)
  447.   { 
  448.     fflush(stdout);
  449.     printf("\nSendFunc: Sending: ");
  450.   }
  451.  
  452.  
  453.   if (!SerialDeviceName)
  454.   { 
  455.     fprintf(stderr, "Line %ld: Must open serial.device first.\n", line->Num);
  456.     exit(10);
  457.   }
  458.  
  459.   if (!StrReadArgs(line->Args, (LONG *) &args, (STRPTR) "ARGS/M"))
  460.   { 
  461.     fprintf(stderr, "Line %ld: Argument or memory error\n", line->Num);
  462.     exit(10);
  463.   }
  464.  
  465.   for(;  *args;  args++)
  466.   { 
  467.     STRPTR send = ParseString(*args);
  468.  
  469.     if (VerboseMode)
  470.       printf(" %s \n", send);
  471.       
  472.     SerialSend(send, strlen((char *) send));
  473.     free(send);
  474.   }
  475.  
  476.   if (VerboseMode)
  477.   { 
  478.     printf("\n");
  479.   }
  480. }
  481. /**
  482. ***  This is similar to "if".
  483. **/
  484. VOID DoGoto(STRPTR Label, int Num)
  485.   struct ScriptLine *sl;
  486.  
  487.   for(sl = (struct ScriptLine *) ScriptLineList.mlh_Head;
  488.         sl->mn.mln_Succ;
  489.         sl = (struct ScriptLine *) sl->mn.mln_Succ)
  490.   { 
  491.     if (sl->Label  &&  strcmp((char *) sl->Label, (char *) Label) == 0)
  492.     { 
  493.       CurrentScriptLine = (struct ScriptLine *) sl->mn.mln_Pred;
  494.       return;
  495.     }
  496.   }
  497.  
  498.   fprintf(stderr, "Line %d: Unknown label.\n", Num);
  499.   exit(10);
  500. }
  501. VOID OnFunc(struct ScriptLine *line)
  502. { STRPTR ptr = line->Args;
  503.  
  504.   if (strnicmp((char *) ptr, "status", 6) == 0)
  505.   { 
  506.     ptr = SkipBlanks(ptr+6);
  507.     if (strnicmp((char *) ptr, "goto", 4) == 0)
  508.     { 
  509.       STRPTR *labels;
  510.       int i;
  511.  
  512.       if (!StrReadArgs(ptr+4, (LONG *) &labels, (STRPTR) "LABELS/M"))
  513.       { 
  514.         fprintf(stderr, "Line %ld: Memory error.\n", line->Num);
  515.           exit(10);
  516.       }
  517.       for (i = -1;  *labels;  ++i, ++labels)
  518.       { 
  519.         if (i == StatusVar)
  520.           { 
  521.           DoGoto(*labels, line->Num);
  522.             return;
  523.           }
  524.       }
  525.       return;
  526.     }
  527.   }
  528.  
  529.   fprintf(stderr, "Line %ld: Condition syntax.", line->Num);
  530.   exit(10);
  531. }
  532. /**
  533. ***  This function waits for certain strings.
  534. **/
  535. VOID WaitFunc(struct ScriptLine *line)
  536.   struct
  537.   { 
  538.     STRPTR *WaitArgs;
  539.     ULONG *TimeOut;
  540.   } args;
  541.   STRPTR* parsedArgs;
  542.   LONG TimeOut;
  543.   int i = 0;
  544.  
  545.   if(VerboseMode)
  546.     printf("\nWaitFunc: line->Args %s \n",line->Args);
  547.     
  548.   if (!SerialDeviceName)
  549.   { 
  550.     fprintf(stderr, "Line %ld: Must open serial.device first.\n", line->Num);
  551.     exit(10);
  552.   }
  553.  
  554.   args.WaitArgs = NULL;
  555.   args.TimeOut = NULL;
  556.  
  557.   if (!(StrReadArgs(line->Args, (LONG *)&args, (STRPTR) "ARGS/M,TIMEOUT/N/K")))
  558.   { 
  559.     fprintf(stderr, "Line %ld: Argument or memory error.\n", line->Num);
  560.     exit(10);
  561.   }
  562.  
  563.   if (!args.WaitArgs)
  564.   { 
  565.     fprintf(stderr, "Line %ld: Missing argument.\n", line->Num);
  566.     exit(10);
  567.   }
  568.   if (!args.TimeOut)
  569.   { 
  570.     fprintf(stderr, "Line %ld: Missing timeout argument.\n", line->Num);
  571.     exit(10);
  572.   }
  573.   TimeOut = *args.TimeOut;
  574.  
  575.  
  576.   while (args.WaitArgs[i])
  577.   { 
  578.     ++i;
  579.   }
  580.  
  581.   if (!(parsedArgs = malloc(sizeof(STRPTR) * (i+1))))
  582.   { 
  583.     perror("malloc");
  584.     exit(10);
  585.   }
  586.  
  587.   for (i = 0;  args.WaitArgs[i];  i++)
  588.   { 
  589.     parsedArgs[i] = ParseString(args.WaitArgs[i]);
  590.   }
  591.   parsedArgs[i] = NULL;
  592.    
  593.   StatusVar = SerialWait(parsedArgs, TimeOut);
  594. }
  595. /**
  596. ***  The delay function waits for a certain amount of time.
  597. **/
  598. VOID DelayFunc(struct ScriptLine *line)
  599.  
  600.   ULONG tics; 
  601.   
  602.   if (VerboseMode)
  603.     printf("DelayFunc: line->Args: %s\n",(char *) line->Args);
  604.     
  605.   tics = (atoi((char *) line->Args) * 50);
  606.  
  607.   if (tics == 0)
  608.   { 
  609.     fprintf(stderr, "DelayFunc: Line %ld: Missing argument.\n", line->Num);
  610.     exit(10);
  611.   }
  612.  
  613.   Delay(tics);
  614. }
  615. /**
  616. ***  And this is the Exit function.
  617. **/
  618. VOID ExitFunc(struct ScriptLine *line)
  619.  
  620.   LONG result = atol((char *) line->Args);
  621.   exit(result);
  622. }
  623. /**
  624. ***  The Goto command
  625. **/
  626. VOID GotoFunc(struct ScriptLine *line)
  627.   STRPTR Label;
  628.  
  629.   if (!(StrReadArgs(line->Args, (LONG *) &Label, (STRPTR) "LABEL/A")))
  630.   { 
  631.     fprintf(stderr, "Line %ld: Missing argument or memory error.\n",
  632.               line->Num);
  633.     exit(10);
  634.   }
  635.   DoGoto(Label, line->Num);
  636. }
  637. /**
  638. ***  This function enters terminal mode.
  639. **/
  640. VOID TermFunc(struct ScriptLine *line)
  641.   struct
  642.   { 
  643.     STRPTR eof;
  644.     ULONG noecho;
  645.     ULONG raw;
  646.   } args;
  647.  
  648.   args.eof = NULL;
  649.   args.noecho = FALSE;
  650.   args.raw = FALSE;
  651.  
  652.   if (!StrReadArgs(line->Args, (LONG *) &args, (STRPTR) "EOF,NOECHO/S,RAW/S"))
  653.   { 
  654.     fprintf(stderr, "Line %ld: Argument or memory error\n", line->Num);
  655.     exit(10);
  656.   }
  657.  
  658.   if (args.eof) 
  659.   {
  660.     args.eof = ParseString(args.eof);
  661.   }
  662.   SerialTerminal(args.eof, !args.noecho, !args.raw);
  663. }
  664. /**
  665. ***  Execute external commands.
  666. **/
  667. VOID SystemFunc(struct ScriptLine *line)
  668.   STRPTR *args;
  669.   int i, result;
  670.   char *cmd;
  671.   STATIC APTR systemBuffer = NULL;
  672.  
  673.   /**
  674.   ***  Initialize buffer.
  675.   **/
  676.   if (!systemBuffer  &&  !(systemBuffer = BufferCreate()))
  677.   { 
  678.     perror("malloc");
  679.     exit(10);
  680.   }
  681.   BufferClear(systemBuffer);
  682.  
  683.  
  684.   if (!StrReadArgs(line->Args, (LONG *) &args, (STRPTR) "ARGS/M"))
  685.   { 
  686.     fprintf(stderr, "Line %ld: Argument or memory error\n", line->Num);
  687.     exit(10);
  688.   }
  689.  
  690.   for(i = 0;  *args;  ++i, ++args)
  691.   { 
  692.     char *str;
  693.  
  694.     if (i)
  695.     { 
  696.       BufferExtend(systemBuffer, (STRPTR) " ", 1);
  697.     }
  698.     str = (char*) ParseString(*args);
  699.     BufferExtend(systemBuffer, (STRPTR) str, strlen(str));
  700.     free(str);
  701.   }
  702.   cmd = (char*) BufferBuffer(systemBuffer);
  703.  
  704.   if (VerboseMode)
  705.   { 
  706.     printf("Executing command: \"%s\"\n", cmd);
  707.   }
  708.   result = system(cmd);
  709.   if (result)
  710.   { 
  711.     if (result > 1  &&  result < 10)  /* Warning */
  712.     { 
  713.       if (VerboseMode)
  714.       { 
  715.         printf("Returned %d.\n", result);
  716.       }
  717.     }
  718.     else
  719.     { printf("Error: Command \"%s\" returned %d.\n", cmd, result);
  720.       exit(result);
  721.     }
  722.   }
  723. }  
  724. /**
  725. ***  Scan the buffer received by the last "wait" command.
  726. **/
  727. VOID ScanFunc(struct ScriptLine *line)
  728.   struct
  729.   { 
  730.     STRPTR format;
  731.     ULONG global;
  732.     ULONG save;
  733.   } args;
  734.   ULONG flags;
  735.  
  736.   args.format = NULL;
  737.   args.global = FALSE;
  738.   args.save = FALSE;
  739.  
  740.   if (!(StrReadArgs(line->Args, (LONG *) &args,
  741.           (STRPTR) "FORMAT/A,GLOBAL/S,SAVE/S")))
  742.   { 
  743.     fprintf(stderr, "Line %ld: Argument or memory error.\n", line->Num);
  744.     exit(10);
  745.   }
  746.  
  747.   flags = 0;
  748.   if (args.save)
  749.   { 
  750.     args.global = TRUE;
  751.     flags |= GVF_SAVE_VAR;
  752.   }
  753.   if (args.global)
  754.   { 
  755.     flags |= GVF_GLOBAL_ONLY;
  756.   }
  757.   else
  758.   { 
  759.     flags |= GVF_LOCAL_ONLY;
  760.   }
  761.  
  762.   StatusVar = Vsscanf(SerialWaitBuffer(), args.format, flags);
  763. }
  764. /**
  765. ***  The SetVar command
  766. **/
  767. void SetVarFunc(struct ScriptLine *line)
  768.   struct 
  769.   {
  770.     STRPTR name;
  771.     STRPTR value;
  772.     ULONG global;
  773.     ULONG save;
  774.   } args;
  775.   int flags;
  776.  
  777.   args.name = NULL;
  778.   args.value = NULL;
  779.   args.global = FALSE;
  780.   args.save = FALSE;
  781.  
  782.   if (!(StrReadArgs(line->Args, (LONG *) &args,
  783.           (STRPTR) "NAME/A,VALUE/A,LOCALONLY/S,GLOBALONLY/S,SAVE/S")))
  784.   { 
  785.     fprintf(stderr, "Line %ld: Missing argument or memory error.\n",
  786.              line->Num);
  787.     exit(10);
  788.   }
  789.  
  790.   flags = 0;
  791.   if (args.save) 
  792.   {
  793.     flags |= GVF_SAVE_VAR;
  794.     args.global = TRUE;
  795.   }
  796.   if (args.global) 
  797.   {
  798.     flags |= GVF_GLOBAL_ONLY;
  799.   } 
  800.   else 
  801.   {
  802.     flags |= GVF_LOCAL_ONLY;
  803.   }
  804.  
  805.   setvar(args.name, args.value, LV_VAR|flags);
  806. }
  807. /**
  808. ***  This is the command table.
  809. **/
  810. struct Command CommandTab[] =
  811. { { EchoFunc,       (STRPTR) "echo"         },
  812.   { DeviceFunc,     (STRPTR) "device"       },
  813.   { SetFunc,        (STRPTR) "set"          },
  814.   { ShowParmsFunc,  (STRPTR) "showparms"    },
  815.   { SendFunc,       (STRPTR) "send"         },
  816.   { OnFunc,         (STRPTR) "on"           },
  817.   { WaitFunc,       (STRPTR) "wait"         },
  818.   { DelayFunc,      (STRPTR) "delay"        },
  819.   { ExitFunc,       (STRPTR) "exit"         },
  820.   { GotoFunc,       (STRPTR) "goto"         },
  821.   { TermFunc,       (STRPTR) "terminal"     },
  822.   { SystemFunc,     (STRPTR) "system"       },
  823.   { ScanFunc,       (STRPTR) "scan"         },
  824.   { SetVarFunc,     (STRPTR) "setvar"       },
  825.   { NULL,           NULL                    }
  826. };
  827. /**
  828. ***  This function is used to process the file. Rather easy,
  829. ***  isn't it? :-)
  830. **/
  831. VOID ProcessFile(VOID)
  832.   for(CurrentScriptLine = (struct ScriptLine *) ScriptLineList.mlh_Head;
  833.       CurrentScriptLine->mn.mln_Succ;
  834.       CurrentScriptLine = (struct ScriptLine *) CurrentScriptLine->mn.mln_Succ)
  835.   { 
  836.     (*CurrentScriptLine->CommFunc)(CurrentScriptLine);
  837.   }
  838. }
  839. /**
  840. ***  This function reads and parses the file.
  841. **/
  842. VOID ParseFile(STRPTR file)
  843.   FILE *fp;
  844.   STATIC UBYTE buffer[4096];
  845.   ULONG linenum = 0;
  846.   ULONG success = TRUE;
  847.  
  848.   if (!(fp = fopen((char *) file, "r")))
  849.   { 
  850.     fprintf(stderr, "Could not open %s for reading.\n", file);
  851.     exit(10);
  852.   }
  853.  
  854.   NewList((struct List *) &ScriptLineList);
  855.  
  856.   while(fgets((char *) buffer, sizeof(buffer), fp))
  857.   { 
  858.     ULONG len = strlen((char *) buffer);
  859.     STRPTR line;
  860.     STRPTR Label = NULL;
  861.     CommandFunc CommFunc;
  862.  
  863.     ++linenum;
  864.  
  865.     if (buffer[len-1] != '\n')
  866.     { 
  867.       fprintf(stderr, "Line %ld too long.\n", linenum);
  868.       exit(10);
  869.     }
  870.  
  871.     if (!(line = malloc(len+1)))
  872.     { 
  873.       perror("malloc");
  874.       exit(10);
  875.     }
  876.     strcpy((char*) line, (char*) buffer);
  877.     
  878.     line = SkipBlanks(line);
  879.  
  880.     /**
  881.     ***  Check for a label
  882.     **/
  883.     { 
  884.       STRPTR ptr = line;
  885.  
  886.       if (isalpha(*ptr))
  887.       { 
  888.         do
  889.           { 
  890.           ++ptr;
  891.           }
  892.           while(isalnum(*ptr));
  893.  
  894.           if (*ptr == ':')
  895.           { 
  896.           *ptr = '\0';
  897.             Label = line;
  898.             line = SkipBlanks(ptr+1);
  899.           }
  900.       }
  901.     }
  902.  
  903.     /**
  904.     ***  Check for empty line or comment line
  905.     **/
  906.     if (*line == ';'  ||  *line == '\r'  ||  *line == '\n')
  907.     { 
  908.       CommFunc = NoneFunc;
  909.       if (!Label)
  910.       { 
  911.         continue;
  912.       }
  913.     }
  914.  
  915.     /**
  916.     ***  If no empty line: Check for command
  917.     **/
  918.     else
  919.     { 
  920.       struct Command *comm;
  921.  
  922.       for (comm = &CommandTab[0];  comm->Func;  ++comm)
  923.       { 
  924.         ULONG len = strlen((char *) comm->Name);
  925.  
  926.           if (strnicmp((char *) comm->Name, (char *) line, len) == 0  &&
  927.              (line[len] == ' '  ||  line[len] == '\t'  ||
  928.               line[len] == '\r' ||  line[len] == '\n'))
  929.           { 
  930.           line = SkipBlanks(line+len);
  931.             CommFunc = comm->Func;
  932.             break;
  933.           }
  934.       }
  935.  
  936.       if (!comm->Func)
  937.       { 
  938.         fprintf(stderr, "Line %ld: Unknown command.\n", linenum);
  939.           success = FALSE;
  940.       }
  941.     }
  942.  
  943.     /**
  944.     ***  Allocate a new scriptline structure.
  945.     **/
  946.     { 
  947.       struct ScriptLine *sl;
  948.  
  949.       if (!(sl = malloc(sizeof(*sl))))
  950.       { 
  951.         perror("malloc");
  952.           exit(10);
  953.       }
  954.  
  955.       AddTail((struct List *) &ScriptLineList, (struct Node *) sl);
  956.       sl->Num = linenum;
  957.       sl->CommFunc = CommFunc;
  958.       sl->Args = line;
  959.       sl->Label = Label;
  960.       /*
  961.       if(VerboseMode)
  962.       {
  963.         printf("\n");
  964.         printf("ParseFile: Num      %d  \n", sl->Num);
  965.         printf("ParseFile: CommFunc 0x%x\n", sl->CommFunc);
  966.         printf("ParseFile: Args     %s  \n", sl->Args);
  967.         printf("ParseFile: Label    %s  \n", sl->Label);
  968.       }
  969.       */
  970.     }
  971.   }
  972.  
  973.   if (ferror(fp))
  974.   { 
  975.     perror("fgets");
  976.     exit(10);
  977.   }
  978.  
  979.   if (!success)
  980.   { 
  981.     exit(10);
  982.   }
  983.  
  984.   fclose(fp);
  985. }
  986. /**
  987. ***  This is the Cleanup() function, called, when the program terminates.
  988. **/
  989. VOID Cleanup(VOID)
  990.   SerialCleanup();
  991.   StrReadArgsFree();
  992.   if (MainRDArgs)
  993.   { 
  994.     FreeArgs(MainRDArgs);
  995.   }
  996. }
  997. /**
  998. ***  This function hints about the GPL.
  999. **/
  1000. VOID ShowGPL(FILE *fp)
  1001.   fprintf(fp, "This program is governed by the terms and conditions of the\n");
  1002.   fprintf(fp, "GNU General Public License. A copy should have come with\n");
  1003.   fprintf(fp, "this distribution. (See the file COPYING.) In that license\n");
  1004.   fprintf(fp, "it is made clear that you are welcome to redistribute either\n");
  1005.   fprintf(fp, "verbatim or modified copies of the program and the documentation\n");
  1006.   fprintf(fp, "under certain conditions. Further you are told that this program\n");
  1007.   fprintf(fp, "comes with ABSOLUTELY NO WARRANTY!\n");
  1008. }
  1009. /**
  1010. ***  This function displays the Usage() message.
  1011. **/
  1012. VOID Usage(VOID)
  1013.   fprintf(stderr, "Usage: IPDial SCRIPT,DEVICE/K,PROTOCOL/K,TERMINAL/S,ECHO/S,VERBOSE/S,HELP/S\n\n");
  1014.   fprintf(stderr, "\tSCRIPT:    Script file to execute.\n");
  1015.   fprintf(stderr, "\tDEVICE:    Device to use (default serial.device)\n");
  1016.   fprintf(stderr, "\tPROTOCOL:  Protocol to use; XONXOFF, 7WIRE (default) or NONE)\n");
  1017.   fprintf(stderr, "\tUNIT:      Unit to use (default 0)\n");
  1018.   fprintf(stderr, "\tECHO:      Show modems replies.\n");
  1019.   fprintf(stderr, "\tVERBOSE:   Be verbose.\n\n");
  1020.   fprintf(stderr, "\tTERMINAL:  Run in terminal mode.\n");
  1021.   fprintf(stderr, "\tHELP:      Print this message.\n");
  1022.   fprintf(stderr, "\n\n%s  @ 1994 by Jochen Wiedmann\n\n", VString);
  1023.   ShowGPL(stderr);
  1024.   exit(5);
  1025. }
  1026. /**
  1027. ***  This is main().
  1028. **/
  1029. int main(int argc, char *argv[])
  1030.   struct
  1031.   { 
  1032.     STRPTR file;
  1033.     STRPTR device;
  1034.     STRPTR protocol;
  1035.     LONG *unit;
  1036.     LONG *baud;
  1037.     ULONG terminal;
  1038.     ULONG help;
  1039.     ULONG echo;
  1040.     ULONG verbose;
  1041.     ULONG raw;
  1042.   } args;
  1043.  
  1044.   args.file = NULL;
  1045.   args.device = (STRPTR) "serial.device";
  1046.   args.protocol = (STRPTR) "7wire";
  1047.   args.unit = NULL;
  1048.   args.baud = NULL;
  1049.   args.terminal = FALSE;
  1050.   args.echo = FALSE;
  1051.   args.verbose = FALSE;
  1052.   args.help = FALSE;
  1053.   args.raw = FALSE;
  1054.  
  1055.   if (!argc)    /*  No WB handling.     */
  1056.   { 
  1057.     exit(-1);
  1058.   }
  1059.  
  1060.   if (atexit(Cleanup))
  1061.   { 
  1062.     fprintf(stderr, "Memory error.\n");
  1063.     exit(20);
  1064.   }
  1065.  
  1066.   if (!(MainRDArgs = ReadArgs((STRPTR) "SCRIPT,DEVICE/K,PROTOCOL/K,"
  1067.                                            "UNIT/K/N,BAUD/K/N,TERMINAL/S,"
  1068.                                              "HELP/S,ECHO/S,VERBOSE/S,RAW/S",
  1069.                                               (LONG *) &args, NULL)))
  1070.   { 
  1071.     fprintf(stderr, "Cannot parse command line.\n");
  1072.   }
  1073.  
  1074.   if (args.help  || (!args.file  &&  !args.terminal))
  1075.   { 
  1076.     Usage();
  1077.   }
  1078.  
  1079.   EchoMode = args.echo;
  1080.   if (args.verbose)
  1081.   { 
  1082.     VerboseMode = TRUE;
  1083.     printf("%s  @ 1994 by Jochen Wiedmann\n\n", VString);
  1084.     ShowGPL(stdout);
  1085.     printf("\n\n");
  1086.   }
  1087.  
  1088.   if (args.terminal)
  1089.   { 
  1090.     if(VerboseMode)
  1091.       printf("\nMain: %d\n",__LINE__);
  1092.       
  1093.     SerialOpen(args.device, args.protocol, args.unit ? *args.unit : 0);
  1094.     if (args.baud)
  1095.     { 
  1096.       if(VerboseMode)
  1097.         printf("\nMain: %d\n",__LINE__);
  1098.       SerialSetBaud(*args.baud);
  1099.     }
  1100.     if(VerboseMode)
  1101.       printf("\nMain: %d\n",__LINE__);
  1102.     SerialTerminal(NULL, TRUE, !args.raw);
  1103.   }
  1104.   else if (args.file)
  1105.   { 
  1106.     if(VerboseMode)
  1107.       printf("\nMain: %d\n",__LINE__);
  1108.     ParseFile(args.file);
  1109.     if(VerboseMode)
  1110.       printf("\nMain: %d\n",__LINE__);
  1111.     ProcessFile();
  1112.   }
  1113.  
  1114.   exit(0);
  1115. }
  1116.